package com.jysz.certificate.service.pm;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.jysz.certificate.constant.ConfigTypeConstants.ConfigTypes;
import com.jysz.certificate.constant.ConfigTypeConstants.PerformanceConfig;
import com.jysz.certificate.persistence.dao.pm.PerformanceAssignDao;
import com.jysz.certificate.persistence.enums.PerformanceAssignStatus;
import com.jysz.certificate.persistence.enums.PostType;
import com.jysz.certificate.persistence.enums.mf.BillStatus;
import com.jysz.certificate.persistence.model.mf.Bill;
import com.jysz.certificate.persistence.model.mf.BillApply;
import com.jysz.certificate.persistence.model.mf.BillOption;
import com.jysz.certificate.persistence.model.pm.AssignUser;
import com.jysz.certificate.persistence.model.pm.PAShopMonthDetail;
import com.jysz.certificate.persistence.model.pm.PerformanceAssign;
import com.jysz.certificate.persistence.model.pm.PerformanceAssignShopDetail;
import com.jysz.certificate.persistence.model.pm.PmUser;
import com.jysz.certificate.persistence.model.pm.PmUserList;
import com.jysz.certificate.persistence.model.pm.UserPerformance;
import com.jysz.certificate.persistence.model.system.Financial;
import com.jysz.certificate.persistence.model.system.Organization;
import com.jysz.certificate.persistence.model.system.Shop;
import com.jysz.certificate.persistence.model.system.User;
import com.jysz.certificate.service.cm.CertificationService;
import com.jysz.certificate.service.core.AttachmentService;
import com.jysz.certificate.service.mf.BillOptionService;
import com.jysz.certificate.service.system.UserService;
import com.jysz.certificate.utils.CertificateUtils;
import com.jysz.certificate.utils.DateUtil;
import com.jysz.webcore.ssh.orm.hibernate.support.Page;
import com.jysz.webcore.ssh.service.EntityService;
import com.jysz.webcore.utils.ReflectionUtils;

/**
 * @author <a href="mailto:javaengine@outlook.com">Kaca Rich</a>
 *
 */
@Service
public class PerformanceAssignService extends EntityService<PerformanceAssign, Long, PerformanceAssignDao>{

	private static final Logger LOG =  LoggerFactory.getLogger(AttachmentService.class);
	@Resource
	private PerformanceAssignDao performanceAssignDao;
	@Resource
	private PmUserService pmUserService;
	@Resource
	private UserService userService;
	@Resource
	private PmUserListService pmUserListService;
	@Resource
	private BillOptionService billOptionService;
	@Resource
	private PerformanceAssignShopDetailService performanceAssignShopDetailService;
	@Resource
	private PAShopMonthDetailService paShopMonthDetailService;
	@Resource
	private CertificationService certificationService;
	@Resource
	private AssignUserService assignUserService;
	@Resource
	private UserPerformanceService userPerformanceService;
	
	@Override
	public PerformanceAssignDao getEntityDao() {
		return performanceAssignDao;
	}
	
	@SuppressWarnings("unchecked")
	public Page<PerformanceAssign> findPage(PerformanceAssign search, int pageNumber,int pageSize, User user){
		Criteria criteria = performanceAssignDao.createCriteria();
		
		if(PostType.Manager.equals(user.getPost())){
			criteria.add(Restrictions.ne("status", PerformanceAssignStatus.NOTSTART));
		}
		
		if(search!= null && StringUtils.isNotBlank(search.getMonthDate())){
			criteria.add(Restrictions.eq("monthDate", search.getMonthDate()));
		}
		criteria.addOrder(Order.desc("id"));
		Page<PerformanceAssign> page = this.findPage(criteria, pageNumber, pageSize);
		
		//计算这个区域经理总额
		if(PostType.Manager.equals(user.getPost()) && page.getResult() != null ){
			for (Iterator<PerformanceAssign> iterator = page.getResult().iterator(); iterator.hasNext();) {
				PerformanceAssign entity =  iterator.next();
				this.getEntityDao().getSession().evict(entity);
				
				entity.setPayinAmount(0);
				entity.setAreaTotalAmount(0);
				entity.setTotalAmount(0);
				
				Criteria shopDetailCriteria = performanceAssignShopDetailService.getEntityDao().createCriteria();
				shopDetailCriteria.add(Restrictions.eq("performanceAssign", entity));
				Criteria shopCriteria = shopDetailCriteria.createCriteria("shop");
				this.getEntityDao().addShopCriteria(shopCriteria, true, user);
				List<PerformanceAssignShopDetail> shopDetails = shopDetailCriteria.list();
				
				if(shopDetails != null){
					for (Iterator<PerformanceAssignShopDetail> iterator2 = shopDetails.iterator(); iterator2
							.hasNext();) {
						PerformanceAssignShopDetail performanceAssignShopDetail = (PerformanceAssignShopDetail) iterator2
								.next();
						
						entity.setPayinAmount(entity.getPayinAmount() + performanceAssignShopDetail.getPayinAmount());
						entity.setAreaTotalAmount(entity.getAreaTotalAmount() + performanceAssignShopDetail.getAreaTotalAmount());
						entity.setTotalAmount(entity.getTotalAmount() + performanceAssignShopDetail.getTotalAmount());
					}
				}

			}
		}
		
		return page;
	}

	/**
	 * @param id
	 */
	public void destoryAndPmUsers(Long id) {
		PerformanceAssign pa = this.find(id);
//		pmUserService.deleteByPerformanceAssign(pa);
		pmUserService.destoryAll(pa.getPmUsers());
		this.destory(pa);
	}

	public void saveGeneratorPaDetails(PerformanceAssign entity) {
			entity.setPayinAmount(0);
			entity.setTotalAmount(0);
			entity.setAreaTotalAmount(0);
			List<Shop> shops = billOptionService.findShopsAtBeforeMonthOfStateCharged(entity.getMonthDate());
			List<String> shopMonths = billOptionService.findShopMonthsAtBeforeMonthOfStateCharged(entity.getMonthDate(), shops);
			
			List<PerformanceAssignShopDetail> paShopDetails = new ArrayList<PerformanceAssignShopDetail>();
			Map<Long, PerformanceAssignShopDetail> paShopDetailMap = new HashMap<Long, PerformanceAssignShopDetail>();
			
			for (Iterator<String> iterator = shopMonths.iterator(); iterator
					.hasNext();) {
				String shopMonth = iterator.next();
				List<PmUserList> pmUserLists = pmUserListService.findByMonthDate(shopMonth, shops);
				
				for (Iterator<PmUserList> iterator2 = pmUserLists.iterator(); iterator2.hasNext();) {
					
					PmUserList pmUserList = iterator2.next();
					String monthDate = pmUserList.getPmUser().getDeliceryMM();
					Long shopId = pmUserList.getShop().getId();
					List<BillOption> billOptions = billOptionService.findBillOptionsAtMonthOfStateCharged(monthDate, pmUserList.getShop());
					billOptions = this.filterBillOptions(billOptions);
					
					if(billOptions == null || billOptions.size() < 1){
						continue;
					}
					
					PerformanceAssignShopDetail paShopDetail = null;
					if(paShopDetailMap.containsKey(shopId)){
						paShopDetail = paShopDetailMap.get(shopId);
					}else{
						paShopDetail = new PerformanceAssignShopDetail();
						List<User> users = this.getAreaUsers(pmUserList);
						
						paShopDetail.setPerformanceAssign(entity);
						paShopDetail.setAreaUsers(users);
						paShopDetail.setShop(pmUserList.getShop());
					
						performanceAssignShopDetailService.save(paShopDetail);
						
						paShopDetail.setPayinAmount(0);//管理费总金额
						paShopDetail.setTotalAmount(0);
						paShopDetail.setAreaTotalAmount(0);
						paShopDetailMap.put(paShopDetail.getShop().getId(), paShopDetail);
						
						paShopDetails.add(paShopDetail);
					}
					
					PAShopMonthDetail paShopMonthDetail = new PAShopMonthDetail();
					
					paShopMonthDetail.setPmUserList(pmUserList);
					paShopMonthDetail.setBillOptions(billOptions);
					
					
					paShopMonthDetail.setMonthDate(monthDate);
					paShopMonthDetail.setPerformanceAssignShopDetail(paShopDetail);
					
					this.calcAmount(paShopMonthDetail);
					
					paShopMonthDetailService.save(paShopMonthDetail);
					
					this.saveGeneratorAssignUsers(paShopMonthDetail);
					
					paShopDetail.setPayinAmount(paShopDetail.getPayinAmount() + paShopMonthDetail.getPayinAmount());//管理费总金额
					paShopDetail.setTotalAmount(paShopDetail.getTotalAmount() + paShopMonthDetail.getTotalAmount());
					paShopDetail.setAreaTotalAmount(paShopDetail.getAreaTotalAmount() + paShopMonthDetail.getAreaTotalAmount());
					
					entity.setPayinAmount(entity.getPayinAmount() + paShopMonthDetail.getPayinAmount());
					entity.setTotalAmount(entity.getTotalAmount() + paShopMonthDetail.getTotalAmount());
					entity.setAreaTotalAmount(entity.getAreaTotalAmount() + paShopMonthDetail.getAreaTotalAmount());
					
				}
			}
		
			
			entity.setPerformanceAssignShopDetails(paShopDetails);

			this.save(entity);
	}
		

	/**
	 * 将绩效分配到人
	 * 
	 * @param paShopMonthDetail
	 */
	private void saveGeneratorAssignUsers(PAShopMonthDetail paShopMonthDetail) {
		List<User> users = paShopMonthDetail.getPmUserList().getUsers();
		if(users == null || users.isEmpty()){
			return;
		}
		
		double avgAmount = 0;
		if(paShopMonthDetail.getTotalAmount() > 0){
			avgAmount = paShopMonthDetail.getTotalAmount() / users.size();
		}
		
		for (Iterator<User> iterator = users.iterator(); iterator.hasNext();) {
			User user = iterator.next();
			AssignUser assignUser = new AssignUser();
			assignUser.setMonthDate(paShopMonthDetail.getMonthDate());
			assignUser.setPaShopMonthDetail(paShopMonthDetail);
			assignUser.setUser(user);
			
			assignUser.setAmount(avgAmount);
			assignUser.setPostType(PostType.Shop);
			
			assignUserService.save(assignUser);
		}
	}

	/**
	 * 计算提成，统计管理费
	 * @param paShopMonthDetail
	 * @return
	 */
	private double calcAmount(PAShopMonthDetail paShopMonthDetail) {
		if(paShopMonthDetail.getBillOptions() == null){
			return 0;
		}
		
		Shop shop = paShopMonthDetail.getPerformanceAssignShopDetail().getShop();
//		int billingQty = 0;
		List<BillOption> billings = new ArrayList<BillOption>();
//		int notBillingQty = 0;
		List<BillOption> notBillings = new ArrayList<BillOption>();
		double payinAmount = 0;
		double notBillingAmount = 0;
		double billingAmount = 0;
		int notBillingsAvaQty = 0;
		int billingsAvaQty = 0;
//		boolean billing = true;
		boolean notBilling = true;
		
		//FIXME:删除这段没必要的过滤，已经在filterBillOptions方法过滤了。
		for (Iterator<BillOption> iterator = paShopMonthDetail.getBillOptions().iterator(); iterator.hasNext();) {
			BillOption billOption = iterator.next();
			Bill chargedBill = this.getChargedBill(billOption);
			BillApply billApply = chargedBill.getBillApply();
			
			//根据店开票。。所有金融机构的钱没收全,不发放绩效。留在下个月收全了再发放。
			if(billApply.getShopFlag() && notBilling){
				//是单独开票，不管是不是，都检查发票是否全收了款
//				if(chargedBill.getAloneOpen()){
					List<Bill>  bills = billApply.getBills();
					for (Iterator<Bill> iterator2 = bills.iterator(); iterator2
							.hasNext();) {
						Bill bill =  iterator2.next();
						
						if(!(BillStatus.FULLCHARGE.equals(bill.getStatus()) || BillStatus.CANCELED.equals(bill.getStatus()) || BillStatus.REDFONT.equals(bill.getStatus()))){
							notBilling = false;//有对应金融机构的钱未收
							break;
						}
					}
					
					if(notBilling){
						if(billOption.getAmount() != null && billOption.getAmount() != 0){
							notBillingsAvaQty++; 
						}
						notBillings.add(billOption);
						payinAmount += billOption.getAmount();
						
					}
			}else{
				if(billOption.getAmount() != null && billOption.getAmount() != 0){
					billingsAvaQty++; 
				}
				billings.add(billOption);
				payinAmount += billOption.getAmount();
			}
			//存在管理费，才算绩效，需要折半处理。
//			if(billOption.getAmount() > 0){
//				if("0".equals(billOption.getFinancial().getBilling())){
//					billings.add(billOption);
//					billingQty += 1;
//				}else{
//					notBillingQty += 1;
//					notBillings.add(billOption);
//				}
//			}
//			payinAmount += billOption.getAmount();
		}
		
		Set<Financial> fins = new HashSet<Financial>();
		ArrayList<BillOption> options = new ArrayList<BillOption>();
		if(billings.size() > 0){
			for (Iterator<BillOption> iterator = billings.iterator(); iterator.hasNext();) {
				BillOption option = iterator.next();
				if(!fins.contains(option.getFinancial())){
					fins.add(option.getFinancial());
				}
				options.add(option);
			}
		}	
		if(notBillings.size() > 0){
			for (Iterator<BillOption> iterator = notBillings.iterator(); iterator.hasNext();) {
				BillOption option = iterator.next();
				if(!fins.contains(option.getFinancial())){
					fins.add(option.getFinancial());
				}
				options.add(option);
			}
		}
		
		paShopMonthDetail.setBillOptions(options);
		Long shopId = paShopMonthDetail.getPerformanceAssignShopDetail().getShop().getId();
		int currenMonthInQty = certificationService.findCertificationInMonth(shopId, paShopMonthDetail.getMonthDate(), fins);
		paShopMonthDetail.setCurrenMonthInQty(currenMonthInQty);
		int preMonthInQty = certificationService.findBeforeCertifcatiionInQty(shopId, paShopMonthDetail.getMonthDate(), fins);
		paShopMonthDetail.setPreMonthInQty(preMonthInQty);
		
		//非独立开票计算方式
		if(notBillingsAvaQty > 0){
			double doneyRoyaltyTiny = shop.getMoneyRoyaltyTiny() == null ? 0 : shop.getMoneyRoyaltyTiny();
			double moneyRoyaltyAdding = shop.getMoneyRoyaltyAdding() == null ? 0 : shop.getMoneyRoyaltyAdding();
			notBillingAmount = doneyRoyaltyTiny + moneyRoyaltyAdding * notBillings.size();
		}
		
		//独立开票计算方式
		if(billingsAvaQty > 0){
			double moneyIndTiny = shop.getMoneyIndTiny() == null ? 0 : shop.getMoneyIndTiny();
			double moneyIndBig = shop.getMoneyIndBig() == null ? 0 : shop.getMoneyIndBig();
			billingAmount = moneyIndTiny + moneyIndBig * billings.size();
		}
		
		double moneyStock = shop.getMoneyStock() == null ? 0 : shop.getMoneyStock();
		double moneyRemain = shop.getMoneyRemain() == null ? 0 : shop.getMoneyRemain();
		double paAmount = paShopMonthDetail.getCurrenMonthInQty() * moneyStock + paShopMonthDetail.getPreMonthInQty() + paShopMonthDetail.getPreMonthInQty() * moneyRemain;
		
		double totoalAmount = paAmount > (notBillingAmount + billingAmount) ? paAmount : notBillingAmount + billingAmount;
		
		paShopMonthDetail.setPayinAmount(payinAmount);
		paShopMonthDetail.setTotalAmount(totoalAmount);
		paShopMonthDetail.setAreaTotalAmount(paAmount);
		
		return payinAmount;
	}

	
	private List<BillOption> filterBillOptions(List<BillOption> billOptions){
		List<BillOption> options = new ArrayList<BillOption>();
		for (Iterator<BillOption> iterator = billOptions.iterator(); iterator.hasNext();) {
			BillOption billOption = iterator.next();
			Bill chargedBill = this.getChargedBill(billOption);
			BillApply billApply = chargedBill.getBillApply();
			boolean notBilling = true;
			//根据店开票。。所有金融机构的钱没收全,不发放绩效。留在下个月收全了再发放。
			if(billApply.getShopFlag() && notBilling){
				//是单独开票，不管是不是，都检查发票是否全收了款
//				if(chargedBill.getAloneOpen()){
					List<Bill>  bills = billApply.getBills();
					for (Iterator<Bill> iterator2 = bills.iterator(); iterator2
							.hasNext();) {
						Bill bill =  iterator2.next();
						
						if(!(BillStatus.FULLCHARGE.equals(bill.getStatus()) || BillStatus.CANCELED.equals(bill.getStatus()) || BillStatus.REDFONT.equals(bill.getStatus()))){
							notBilling = false;//有对应金融机构的钱未收
							break;
						}
					}
					
					if(notBilling){
						options.add(billOption);
					}
			}else{
				options.add(billOption);
			}
		}
	
		return options;
	}
	/**
	 * 获取实收的发票
	 * @param billOption
	 * @return
	 */
	private Bill getChargedBill(BillOption billOption) {
		List<Bill> bills = billOption.getBills();
		Bill bill = null;
		for (Iterator<Bill> iterator = bills.iterator(); iterator.hasNext();) {
			bill = iterator.next();
			
			if(BillStatus.FULLCHARGE.equals(bill.getStatus())){
				break;
			}
			
		}
		return bill;
	}

	@SuppressWarnings("unchecked")
	public List<User> getAreaUsers(PmUserList pmUserList) {
		List<User> users = null;
		List<Organization> areaOrgUsers = pmUserList.getOrganization().getStaffChilds();
		
		if(areaOrgUsers != null && areaOrgUsers.size() > 0){
			List<Long> userids = ReflectionUtils.convertElementPropertyToList(areaOrgUsers, "objectId");
			users = userService.findByIds(userids);
		}
		return users;
	}

	/**
	 * 绩效分配
	 * @param entity
	 */
	public void saveConfirmAssign(PerformanceAssign entity) {
		
		//FIXME:重构。。
		List<PAShopMonthDetail> paShopMonthDetails = paShopMonthDetailService.findByPerformanceAssign(entity);
		Map<Long, UserPerformance> userPerformanceMap = new HashMap<Long, UserPerformance>();
		Map<Long, UserPerformance> shopPerformanceMap = new HashMap<Long, UserPerformance>();
		Map<Long, UserPerformance> areaPerformanceMap = new HashMap<Long, UserPerformance>();//区域绩效map,为空根据组织架构ID生成。。
		
		for (Iterator<PAShopMonthDetail> iterator = paShopMonthDetails.iterator(); iterator
				.hasNext();) {
			PAShopMonthDetail paShopMonthDetail = iterator.next();
			List<User> areaUsers = paShopMonthDetail.getPerformanceAssignShopDetail().getAreaUsers();
			Organization org = paShopMonthDetail.getPerformanceAssignShopDetail().getShop().getArea();
			
			if(areaUsers != null && areaUsers.size() > 0){
				//区域经理根据人员数量求平均值
				double amount =  paShopMonthDetail.getAreaTotalAmount() != 0 ? paShopMonthDetail.getAreaTotalAmount() / areaUsers.size() : 0;
				for (Iterator<User> iterator2 = areaUsers.iterator(); iterator2.hasNext();) {
					User user = iterator2.next();
					
					AssignUser assignUser = new AssignUser();
					assignUser.setMonthDate(paShopMonthDetail.getMonthDate());
					assignUser.setPaShopMonthDetail(paShopMonthDetail);
					assignUser.setUser(user);
					assignUser.setAmount(amount);
					assignUser.setPostType(PostType.Manager);
					
					assignUserService.save(assignUser);
					
					UserPerformance userPerformance = null;
					
					if(!userPerformanceMap.containsKey(user.getId())){
						userPerformance = new UserPerformance();
						userPerformance.setAmount(0);
						userPerformance.setPerformanceAssign(entity);
						userPerformance.setMonthDate(entity.getMonthDate());
						userPerformance.setStatus(PerformanceAssignStatus.ASSIGN);
						userPerformance.setUser(user);
						
						userPerformanceMap.put(user.getId(), userPerformance);
					}else{
						userPerformance = userPerformanceMap.get(user.getId());
					}
					
					List<AssignUser> users = userPerformance.getAssignUsers();
					if(users == null){
						users = new ArrayList<AssignUser>();
					}
					
					users.add(assignUser);
					userPerformance.setAssignUsers(users);
					userPerformance.setAmount(userPerformance.getAmount() + assignUser.getAmount());
					userPerformanceService.save(userPerformance);
//					List<PAShopMonthDetail> monthDetails = userPerformance.getPaShopMonthDetails();
//					if(monthDetails == null){
//						monthDetails = new ArrayList<PAShopMonthDetail>();
//					}
//					
//					monthDetails.add(paShopMonthDetail);
//					userPerformance.setPaShopMonthDetails(monthDetails);
					
//					userPerformance.setAmount(userPerformance.getAmount() + amount);
//					userPerformanceService.save(userPerformance);
					
					
				}
			}else{
				AssignUser assignUser = new AssignUser();
				assignUser.setMonthDate(paShopMonthDetail.getMonthDate());
				assignUser.setPaShopMonthDetail(paShopMonthDetail);
				assignUser.setUser(null);
				assignUser.setAmount(paShopMonthDetail.getAreaTotalAmount());
				assignUser.setPostType(PostType.Manager);
				
				assignUserService.save(assignUser);
				
				UserPerformance userPerformance = null;
				if(!areaPerformanceMap.containsKey(org.getId())){
					userPerformance = new UserPerformance();
					
					userPerformance.setAmount(0);
					userPerformance.setStatus(PerformanceAssignStatus.ASSIGN);
					userPerformance.setMonthDate(entity.getMonthDate());
					userPerformance.setPerformanceAssign(entity);
					
					userPerformance.setArea(org);
					
					areaPerformanceMap.put(org.getId(), userPerformance);
				}else{
					userPerformance = areaPerformanceMap.get(org.getId());
				}
				
				List<AssignUser> users = userPerformance.getAssignUsers();
				if(users == null){
					users = new ArrayList<AssignUser>();
				}
				
				users.add(assignUser);
				userPerformance.setAssignUsers(users);
				userPerformance.setAmount(userPerformance.getAmount() + assignUser.getAmount());
				userPerformanceService.save(userPerformance);

			}
			
			//驻店员绩效
			List<AssignUser> assignUsers = paShopMonthDetail.getAssignUsers();
			
			if(assignUsers == null || assignUsers.size() < 1){ 
				AssignUser assignUser = new AssignUser();
				assignUser.setMonthDate(paShopMonthDetail.getMonthDate());
				assignUser.setPaShopMonthDetail(paShopMonthDetail);
				assignUser.setUser(null);
				assignUser.setAmount(paShopMonthDetail.getAreaTotalAmount());
				assignUser.setPostType(PostType.Shop);
				assignUserService.save(assignUser);
				
				//根据店铺月份创建一个新的无人员的绩效对象。
				UserPerformance userPerformance = null;
				
				if(!shopPerformanceMap.containsKey(paShopMonthDetail.getPerformanceAssignShopDetail().getId())){
					userPerformance = new UserPerformance();
					userPerformance.setAmount(0);
					userPerformance.setStatus(PerformanceAssignStatus.ASSIGN);
					userPerformance.setMonthDate(entity.getMonthDate());
					userPerformance.setPerformanceAssign(entity);
					userPerformance.setShop(paShopMonthDetail.getPerformanceAssignShopDetail().getShop());
					
					shopPerformanceMap.put(paShopMonthDetail.getPerformanceAssignShopDetail().getId(), userPerformance);
				}else{
					userPerformance = shopPerformanceMap.get(paShopMonthDetail.getPerformanceAssignShopDetail().getId());
				}
				
				List<AssignUser> users = userPerformance.getAssignUsers();
				if(users == null){
					users = new ArrayList<AssignUser>();
				}
				
				users.add(assignUser);
				userPerformance.setAssignUsers(users);
				userPerformance.setAmount(userPerformance.getAmount() + assignUser.getAmount());
				userPerformanceService.save(userPerformance);
				
			}else{
				for (Iterator<AssignUser> iterator2 = assignUsers.iterator(); iterator2
						.hasNext();) {
					AssignUser assignUser =  iterator2.next();
					UserPerformance userPerformance = null;
					
					if(!userPerformanceMap.containsKey(assignUser.getUser().getId())){
						userPerformance = new UserPerformance();
						userPerformance.setAmount(0);
						userPerformance.setPerformanceAssign(entity);
						userPerformance.setMonthDate(entity.getMonthDate());
						userPerformance.setStatus(PerformanceAssignStatus.ASSIGN);
						userPerformance.setUser(assignUser.getUser());
						
						userPerformanceMap.put(assignUser.getUser().getId(), userPerformance);
					}else{
						userPerformance = userPerformanceMap.get(assignUser.getUser().getId());
					}
					
					List<AssignUser> users = userPerformance.getAssignUsers();
					if(users == null){
						users = new ArrayList<AssignUser>();
					}
					
					users.add(assignUser);
					userPerformance.setAssignUsers(users);
					userPerformance.setAmount(userPerformance.getAmount() + assignUser.getAmount());
					userPerformanceService.save(userPerformance);
				}
			}
			
			this.markBillOption(paShopMonthDetail.getBillOptions());
			
		}
	}

	
	private void markBillOption(List<BillOption> billOptions) {
		for (Iterator<BillOption> iterator = billOptions.iterator(); iterator.hasNext();) {
			BillOption billOption = iterator.next();
			billOption.setHasAssigned(true);
			billOptionService.save(billOption);
		}
	}

	/**
	 * 财务 确认 
	 * @param entity
	 */
	public void savePmConfirm(PerformanceAssign entity) {
		entity.setStatus(PerformanceAssignStatus.PM_CONFIRM);
		List<UserPerformance> userPerformances = entity.getUserPerformances();
		
		if(userPerformances == null){
			return;
		}
		
		for (Iterator<UserPerformance> iterator = userPerformances.iterator(); iterator
				.hasNext();) {
			UserPerformance userPerformance = iterator.next();
			userPerformance.setStatus(PerformanceAssignStatus.PM_CONFIRM);
			userPerformanceService.save(userPerformance);
		}
		
	}

	public void saveAreaConfirm(PerformanceAssign entity, User user) {
		Date date = DateUtil.getDate();
		List<PerformanceAssignShopDetail> details = performanceAssignShopDetailService.findAreaShopDetailsByPerformanceAssign(entity);
		if(details != null){
			for (Iterator<PerformanceAssignShopDetail> iterator = details.iterator(); iterator.hasNext();) {
				PerformanceAssignShopDetail performanceAssignShopDetail = (PerformanceAssignShopDetail) iterator
						.next();
				performanceAssignShopDetail.setConfirmDate(date);
				performanceAssignShopDetail.setConfirmUser(user);
				performanceAssignShopDetail.setStatus(PerformanceAssignStatus.CONFIRM);
				performanceAssignShopDetailService.save(performanceAssignShopDetail);
			}
		}
		
		entity.setStatus(performanceAssignShopDetailService.getPmStatusByUser(entity, null));
		
		this.save(entity);

	}
	
	//绩效定时任务
	public void createJob(){
		
		//获取系统设置的生成日期
		Integer d = CertificateUtils.getIntegerPropertyByKeys(ConfigTypes.PERFORMANCE_CONFIG.getKey(), 
				PerformanceConfig.PM_CONFIRM_FINISH_DAY_QTY.getField());
		//获取今天的日期
		Integer today=DateUtil.getDay();
		if(d!=null&&d>0){
			//今天等于系统设置的日期  或者系统设置的日期大于今天且今天是本月最后一天
			if(d==today||(d>today&&DateUtil.isEndOfTheMonth(new Date()))){
				LOG.debug("开始执行生成月份人员名单定时任务");
				try {
					List<Shop> shops = billOptionService.findShopsAtBeforeMonthOfStateCharged(d.toString());
					Map<String,Map<Long, Organization>> monthMap = new HashMap<String, Map<Long,Organization>>();
					List<PmUser> genPmUsers = new ArrayList<PmUser>();
					
					for (Iterator<Shop> iterator = shops.iterator(); iterator.hasNext();) {
						Shop shop =  iterator.next();
						List<String> shopMonths = billOptionService.findShopMonthsAtBeforeMonthOfStateCharged(d.toString(), shop);
						
						if(shopMonths != null){
							for (Iterator<String> iterator2 = shopMonths.iterator(); iterator2
									.hasNext();) {
								String shopMonth = iterator2.next();
								
								List<PmUserList> pmUserLists = pmUserListService.findByMonthDate(shopMonth, shop);
								Map<Long, PmUserList> pmUserListMap = this.convertToShopIdKeyMap(pmUserLists);
								if(!pmUserListMap.containsKey(shop.getId())){
									Organization area = shop.getArea();
									
									if(area == null){
										LOG.error("生成月份人员名单定时任务:组织架构区域设置存在问题，请联系管理员！店铺 \"" + shop.getShopName() +"\"");
									}else{
										Map<Long, Organization> areaMap = monthMap.get(monthMap);
										areaMap = areaMap == null ? new HashMap<Long, Organization>() : areaMap;
										if(!areaMap.containsKey(area.getId())){
											//没找 到相关区域的根据区域生成人员名单。
											genPmUsers.add(pmUserService.saveGeneratorPmUser(area, shopMonth, null));
											areaMap.put(area.getId(), area);
											
											monthMap.put(shopMonth, areaMap);
										}
									}
									
								}
							}
						}
					}
				} catch (Exception e) {
					LOG.debug("执行生成月份人员名单定时任务发生异常："+e.getMessage());
				}
			}
		}
		
	}
	
	private Map<Long, PmUserList> convertToShopIdKeyMap(List<PmUserList> pmUserLists) {
		Map<Long, PmUserList> result = new HashMap<Long, PmUserList>();
		if(pmUserLists == null){
			return result;
		}
		
		for (Iterator<PmUserList> iterator = pmUserLists.iterator(); iterator.hasNext();) {
			PmUserList pmUserList = iterator.next();
			result.put(pmUserList.getShop().getId(), pmUserList);
		}
		return result;
	}

	/**
	 * 是否存在未分配的绩效
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public boolean isExistNoAssignPm() {
		Criteria criteria = this.getEntityDao().createCriteria();
		criteria.add(Restrictions.le("status", PerformanceAssignStatus.ASSIGN));
		
		List reslut = criteria.list();
		
		return reslut == null || reslut.isEmpty() ? false : true;
	}
	
}
